package com.pzh.xzh.uaa.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.AccessTokenConverter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;

@Configuration
public class MyAuthorizationConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthorizationCodeServices authorizationCodeServices;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private JwtAccessTokenConverter accessTokenConverter;
    /**
     * 令牌端安全策略
     * @param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
                .tokenKeyAccess("permitAll()")
                .checkTokenAccess("permitAll()")
                .allowFormAuthenticationForClients();//表单认证
    }

    /**
     * 客服端配置
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()//内存方式
                .withClient("c1")//客户端id
                .secret(new BCryptPasswordEncoder().encode("xzh"))//密码授权
                .resourceIds("salary") //客户端资源列表
                .authorizedGrantTypes("authorization_code","password",
                        "client_credentials","implicit","refresh_code") //授权方式
                .scopes("all")//允许授权范围
                .autoApprove(false)//跳转
                .redirectUris("www.baidu.com");//授权回调
    }

    /**
     * 令牌访问端和令牌服务  端点服务i
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
//                pathMapping()
                .authenticationManager(authenticationManager) //认证管理器
                .userDetailsService(userDetailsService)  //密码用户模式
                .authorizationCodeServices(authorizationCodeServices) //授权码模式
                .tokenServices(tokenServices()) //令牌管理器
                .allowedTokenEndpointRequestMethods(HttpMethod.POST); //限制post方式
    }

    public AuthorizationServerTokenServices tokenServices(){
        DefaultTokenServices services=new DefaultTokenServices();
        services.setClientDetailsService(clientDetailsService); //设置客户端详细信息
        services.setSupportRefreshToken(true);//设置token自动刷新
        services.setTokenStore(tokenStore);//设置token获取--内存
        services.setTokenEnhancer(accessTokenConverter);
        services.setAccessTokenValiditySeconds(7200);//设置token有效时间 2h
        services.setRefreshTokenValiditySeconds(7200);//刷新令牌默认时间
        return services;
    }

    //授权码模式
    @Bean
    public AuthorizationCodeServices authorizationCodeServices(){
        return new InMemoryAuthorizationCodeServices();
    }
}
